package bpmn.diagram.providers;

import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;

import bpmn.BpmnPackage;
import bpmn.diagram.edit.parts.AssociationEditPart;
import bpmn.diagram.edit.parts.ComplexEditPart;
import bpmn.diagram.edit.parts.DataBasedEditPart;
import bpmn.diagram.edit.parts.DataObjectEditPart;
import bpmn.diagram.edit.parts.EndEditPart;
import bpmn.diagram.edit.parts.InclusiveEditPart;
import bpmn.diagram.edit.parts.IntermediateEditPart;
import bpmn.diagram.edit.parts.Lane2EditPart;
import bpmn.diagram.edit.parts.LaneEditPart;
import bpmn.diagram.edit.parts.ParallelEditPart;
import bpmn.diagram.edit.parts.PoolEditPart;
import bpmn.diagram.edit.parts.Process2EditPart;
import bpmn.diagram.edit.parts.ProcessEditPart;
import bpmn.diagram.edit.parts.SequenceFlowEditPart;
import bpmn.diagram.edit.parts.StartEditPart;
import bpmn.diagram.edit.parts.Task2EditPart;
import bpmn.diagram.edit.parts.Task3EditPart;
import bpmn.diagram.edit.parts.Task4EditPart;
import bpmn.diagram.edit.parts.Task5EditPart;
import bpmn.diagram.edit.parts.Task6EditPart;
import bpmn.diagram.edit.parts.Task7EditPart;
import bpmn.diagram.edit.parts.Task8EditPart;
import bpmn.diagram.edit.parts.Task9EditPart;
import bpmn.diagram.edit.parts.TaskEditPart;
import bpmn.diagram.part.Bpmn_1_1DiagramEditorPlugin;

/**
 * @generated
 */
public class Bpmn_1_1ElementTypes {

	/**
	 * @generated
	 */
	private Bpmn_1_1ElementTypes() {
	}

	/**
	 * @generated
	 */
	private static Map<IElementType, ENamedElement> elements;

	/**
	 * @generated
	 */
	private static ImageRegistry imageRegistry;

	/**
	 * @generated
	 */
	private static Set<IElementType> KNOWN_ELEMENT_TYPES;

	/**
	 * @generated
	 */
	public static final IElementType Process_1000 = getElementType("GMF-BPMN.diagram.Process_1000"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Pool_2003 = getElementType("GMF-BPMN.diagram.Pool_2003"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Process_3001 = getElementType("GMF-BPMN.diagram.Process_3001"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3002 = getElementType("GMF-BPMN.diagram.Task_3002"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3009 = getElementType("GMF-BPMN.diagram.Task_3009"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3014 = getElementType("GMF-BPMN.diagram.Task_3014"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3015 = getElementType("GMF-BPMN.diagram.Task_3015"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3016 = getElementType("GMF-BPMN.diagram.Task_3016"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3017 = getElementType("GMF-BPMN.diagram.Task_3017"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3018 = getElementType("GMF-BPMN.diagram.Task_3018"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3019 = getElementType("GMF-BPMN.diagram.Task_3019"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Task_3020 = getElementType("GMF-BPMN.diagram.Task_3020"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Start_3003 = getElementType("GMF-BPMN.diagram.Start_3003"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Intermediate_3004 = getElementType("GMF-BPMN.diagram.Intermediate_3004"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType End_3005 = getElementType("GMF-BPMN.diagram.End_3005"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType DataObject_3006 = getElementType("GMF-BPMN.diagram.DataObject_3006"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Inclusive_3010 = getElementType("GMF-BPMN.diagram.Inclusive_3010"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Complex_3011 = getElementType("GMF-BPMN.diagram.Complex_3011"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Parallel_3012 = getElementType("GMF-BPMN.diagram.Parallel_3012"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType DataBased_3013 = getElementType("GMF-BPMN.diagram.DataBased_3013"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Lane_3007 = getElementType("GMF-BPMN.diagram.Lane_3007"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Lane_3008 = getElementType("GMF-BPMN.diagram.Lane_3008"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType SequenceFlow_4001 = getElementType("GMF-BPMN.diagram.SequenceFlow_4001"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Association_4002 = getElementType("GMF-BPMN.diagram.Association_4002"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	private static ImageRegistry getImageRegistry() {
		if (imageRegistry == null) {
			imageRegistry = new ImageRegistry();
		}
		return imageRegistry;
	}

	/**
	 * @generated
	 */
	private static String getImageRegistryKey(ENamedElement element) {
		return element.getName();
	}

	/**
	 * @generated
	 */
	private static ImageDescriptor getProvidedImageDescriptor(
			ENamedElement element) {
		if (element instanceof EStructuralFeature) {
			EStructuralFeature feature = ((EStructuralFeature) element);
			EClass eContainingClass = feature.getEContainingClass();
			EClassifier eType = feature.getEType();
			if (eContainingClass != null && !eContainingClass.isAbstract()) {
				element = eContainingClass;
			} else if (eType instanceof EClass
					&& !((EClass) eType).isAbstract()) {
				element = eType;
			}
		}
		if (element instanceof EClass) {
			EClass eClass = (EClass) element;
			if (!eClass.isAbstract()) {
				return Bpmn_1_1DiagramEditorPlugin.getInstance()
						.getItemImageDescriptor(
								eClass.getEPackage().getEFactoryInstance()
										.create(eClass));
			}
		}
		// TODO : support structural features
		return null;
	}

	/**
	 * @generated
	 */
	public static ImageDescriptor getImageDescriptor(ENamedElement element) {
		String key = getImageRegistryKey(element);
		ImageDescriptor imageDescriptor = getImageRegistry().getDescriptor(key);
		if (imageDescriptor == null) {
			imageDescriptor = getProvidedImageDescriptor(element);
			if (imageDescriptor == null) {
				imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
			}
			getImageRegistry().put(key, imageDescriptor);
		}
		return imageDescriptor;
	}

	/**
	 * @generated
	 */
	public static Image getImage(ENamedElement element) {
		String key = getImageRegistryKey(element);
		Image image = getImageRegistry().get(key);
		if (image == null) {
			ImageDescriptor imageDescriptor = getProvidedImageDescriptor(element);
			if (imageDescriptor == null) {
				imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
			}
			getImageRegistry().put(key, imageDescriptor);
			image = getImageRegistry().get(key);
		}
		return image;
	}

	/**
	 * @generated
	 */
	public static ImageDescriptor getImageDescriptor(IAdaptable hint) {
		ENamedElement element = getElement(hint);
		if (element == null) {
			return null;
		}
		return getImageDescriptor(element);
	}

	/**
	 * @generated
	 */
	public static Image getImage(IAdaptable hint) {
		ENamedElement element = getElement(hint);
		if (element == null) {
			return null;
		}
		return getImage(element);
	}

	/**
	 * Returns 'type' of the ecore object associated with the hint.
	 * 
	 * @generated
	 */
	public static ENamedElement getElement(IAdaptable hint) {
		Object type = hint.getAdapter(IElementType.class);
		if (elements == null) {
			elements = new IdentityHashMap<IElementType, ENamedElement>();

			elements.put(Process_1000, BpmnPackage.eINSTANCE.getProcess());

			elements.put(Pool_2003, BpmnPackage.eINSTANCE.getPool());

			elements.put(Process_3001, BpmnPackage.eINSTANCE.getProcess());

			elements.put(Task_3002, BpmnPackage.eINSTANCE.getTask());

			elements.put(Task_3009, BpmnPackage.eINSTANCE.getTask());

			elements.put(Task_3014, BpmnPackage.eINSTANCE.getTask());

			elements.put(Task_3015, BpmnPackage.eINSTANCE.getTask());

			elements.put(Task_3016, BpmnPackage.eINSTANCE.getTask());

			elements.put(Task_3017, BpmnPackage.eINSTANCE.getTask());

			elements.put(Task_3018, BpmnPackage.eINSTANCE.getTask());

			elements.put(Task_3019, BpmnPackage.eINSTANCE.getTask());

			elements.put(Task_3020, BpmnPackage.eINSTANCE.getTask());

			elements.put(Start_3003, BpmnPackage.eINSTANCE.getStart());

			elements.put(Intermediate_3004,
					BpmnPackage.eINSTANCE.getIntermediate());

			elements.put(End_3005, BpmnPackage.eINSTANCE.getEnd());

			elements.put(DataObject_3006, BpmnPackage.eINSTANCE.getDataObject());

			elements.put(Inclusive_3010, BpmnPackage.eINSTANCE.getInclusive());

			elements.put(Complex_3011, BpmnPackage.eINSTANCE.getComplex());

			elements.put(Parallel_3012, BpmnPackage.eINSTANCE.getParallel());

			elements.put(DataBased_3013, BpmnPackage.eINSTANCE.getDataBased());

			elements.put(Lane_3007, BpmnPackage.eINSTANCE.getLane());

			elements.put(Lane_3008, BpmnPackage.eINSTANCE.getLane());

			elements.put(SequenceFlow_4001,
					BpmnPackage.eINSTANCE.getSequenceFlow());

			elements.put(Association_4002,
					BpmnPackage.eINSTANCE.getAssociation());
		}
		return (ENamedElement) elements.get(type);
	}

	/**
	 * @generated
	 */
	private static IElementType getElementType(String id) {
		return ElementTypeRegistry.getInstance().getType(id);
	}

	/**
	 * @generated
	 */
	public static boolean isKnownElementType(IElementType elementType) {
		if (KNOWN_ELEMENT_TYPES == null) {
			KNOWN_ELEMENT_TYPES = new HashSet<IElementType>();
			KNOWN_ELEMENT_TYPES.add(Process_1000);
			KNOWN_ELEMENT_TYPES.add(Pool_2003);
			KNOWN_ELEMENT_TYPES.add(Process_3001);
			KNOWN_ELEMENT_TYPES.add(Task_3002);
			KNOWN_ELEMENT_TYPES.add(Task_3009);
			KNOWN_ELEMENT_TYPES.add(Task_3014);
			KNOWN_ELEMENT_TYPES.add(Task_3015);
			KNOWN_ELEMENT_TYPES.add(Task_3016);
			KNOWN_ELEMENT_TYPES.add(Task_3017);
			KNOWN_ELEMENT_TYPES.add(Task_3018);
			KNOWN_ELEMENT_TYPES.add(Task_3019);
			KNOWN_ELEMENT_TYPES.add(Task_3020);
			KNOWN_ELEMENT_TYPES.add(Start_3003);
			KNOWN_ELEMENT_TYPES.add(Intermediate_3004);
			KNOWN_ELEMENT_TYPES.add(End_3005);
			KNOWN_ELEMENT_TYPES.add(DataObject_3006);
			KNOWN_ELEMENT_TYPES.add(Inclusive_3010);
			KNOWN_ELEMENT_TYPES.add(Complex_3011);
			KNOWN_ELEMENT_TYPES.add(Parallel_3012);
			KNOWN_ELEMENT_TYPES.add(DataBased_3013);
			KNOWN_ELEMENT_TYPES.add(Lane_3007);
			KNOWN_ELEMENT_TYPES.add(Lane_3008);
			KNOWN_ELEMENT_TYPES.add(SequenceFlow_4001);
			KNOWN_ELEMENT_TYPES.add(Association_4002);
		}
		return KNOWN_ELEMENT_TYPES.contains(elementType);
	}

	/**
	 * @generated
	 */
	public static IElementType getElementType(int visualID) {
		switch (visualID) {
		case ProcessEditPart.VISUAL_ID:
			return Process_1000;
		case PoolEditPart.VISUAL_ID:
			return Pool_2003;
		case Process2EditPart.VISUAL_ID:
			return Process_3001;
		case TaskEditPart.VISUAL_ID:
			return Task_3002;
		case Task2EditPart.VISUAL_ID:
			return Task_3009;
		case Task3EditPart.VISUAL_ID:
			return Task_3014;
		case Task4EditPart.VISUAL_ID:
			return Task_3015;
		case Task5EditPart.VISUAL_ID:
			return Task_3016;
		case Task6EditPart.VISUAL_ID:
			return Task_3017;
		case Task7EditPart.VISUAL_ID:
			return Task_3018;
		case Task8EditPart.VISUAL_ID:
			return Task_3019;
		case Task9EditPart.VISUAL_ID:
			return Task_3020;
		case StartEditPart.VISUAL_ID:
			return Start_3003;
		case IntermediateEditPart.VISUAL_ID:
			return Intermediate_3004;
		case EndEditPart.VISUAL_ID:
			return End_3005;
		case DataObjectEditPart.VISUAL_ID:
			return DataObject_3006;
		case InclusiveEditPart.VISUAL_ID:
			return Inclusive_3010;
		case ComplexEditPart.VISUAL_ID:
			return Complex_3011;
		case ParallelEditPart.VISUAL_ID:
			return Parallel_3012;
		case DataBasedEditPart.VISUAL_ID:
			return DataBased_3013;
		case LaneEditPart.VISUAL_ID:
			return Lane_3007;
		case Lane2EditPart.VISUAL_ID:
			return Lane_3008;
		case SequenceFlowEditPart.VISUAL_ID:
			return SequenceFlow_4001;
		case AssociationEditPart.VISUAL_ID:
			return Association_4002;
		}
		return null;
	}

}
